﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace System.Map
{
    /// <summary>
    /// 位置，经纬度坐标
    /// </summary>
    public class Location
    {
        /// <summary>
        /// 纬度
        /// </summary>
        public double Lat { get; set; }

        /// <summary>
        /// 经度
        /// </summary>
        public double Lng { get; set; }
        /// <summary>
        /// 计算二百度坐标点间的距离
        /// </summary>
        /// <param name="location"></param>
        /// <returns></returns>
        public double Distance(Location location)
        {
            this.Lng = GetLoop(this.Lng, -180, 180);
            this.Lat = GetRange(this.Lat, -74, 74);
            location.Lng = GetLoop(location.Lng, -180, 180);
            location.Lat = GetRange(location.Lat, -74, 74);
            var cJ = ToRadians(this.Lng);
            var cM = ToRadians(this.Lat);
            var T = ToRadians(location.Lng);
            var cK = ToRadians(location.Lat);
            return GetDistance(cJ, T, cM, cK);

        }
        
        private static double ToRadians(double T)
        {
            return Math.PI * T / 180;
        }
        private static double GetRange(double cK, double cJ, double T)
        {
            cK = Math.Max(cK, cJ);
            cK = Math.Min(cK, T);
            return cK;
        }
        private static double GetLoop(double cK, double cJ, double T)
        {
            while (cK > T)
            {
                cK -= T - cJ;
            }
            while (cK < cJ)
            {
                cK += T - cJ;
            }
            return cK;
        }
        /// <summary>
        /// 地球半径
        /// </summary>
        private const double EarthRadius = 6370996.81;
        /// <summary>
        /// From Baidu Api javascript source code
        /// </summary>
        /// <param name="cJ"></param>
        /// <param name="T"></param>
        /// <param name="cL"></param>
        /// <param name="cK"></param>
        /// <returns></returns>
        private static double GetDistance(double cJ, double T, double cL, double cK)
        {
            // return this.EARTHRADIUS*Math.acos((Math.sin(cL)*Math.sin(cK)+Math.cos(cL)*Math.cos(cK)*Math.cos(T-cJ)))
            return EarthRadius * Math.Acos((Math.Sin(cL) * Math.Sin(cK) + Math.Cos(cL) * Math.Cos(cK) * Math.Cos(T - cJ)));
        }

    }
    public class Point
    {
        public double X { get; set; }
        public double Y { get; set; }
    }
}
